import { FunctionPrimitive } from '@xenopomp/advanced-types';
import axios, { CreateAxiosDefaults } from 'axios';
import { ConditionalExcept } from 'type-fest';

import { AuthStore } from '../zustand/stores/useAuthStore.ts';

/** Общие настройки для всех экземпляров. */
const options: CreateAxiosDefaults = {
  baseURL: `${import.meta.env.VITE_BACKEND_URL}/api-cafe`, // 👈 Префикс API
  headers: {
    'Content-Type': 'application/json',
  },
};

/**
 * Этот экземпляр класса AxiosInstance отвечает
 * за все запросы к бекенду, не включающие в себя Bearer token.
 */
const axiosClassic = axios.create(options);

/**
 * Этот экземпляр класса AxiosInstance отвечает
 * за все запросы к бекенду, в которых необходимо предоставлять
 * Bearer token.
 */
const axiosWithAuth = axios.create(options);

// Навешиваем на axiosWithAuth интерцепторы (функции, которые будут вызываться в момент
// запроса).

/** Убираем из типа все функции */
type AuthStoreObject = {
  state: ConditionalExcept<AuthStore, FunctionPrimitive>;
};

/**
 * Добавляем в каждый запрос заголовок
 * «Authorization: Bearer ${userToken}»
 */
axiosWithAuth.interceptors.request.use(config => {
  // Парсим локальное хранилище и получаем Bearer token.
  const {
    state: { userToken },
  }: AuthStoreObject = JSON.parse(
    window.localStorage.getItem('app-auth-store') || '{}',
  );

  // Добавляем заголовок с авторизацией только если
  // пользователю был выдан токен (значит, что он авторизовался).
  if (config?.headers && userToken)
    config.headers.Authorization = `Bearer ${userToken}`;

  return config;
});

// Экспортируем инстансы
export { axiosClassic, axiosWithAuth };
